#include "Json.h"
static unsigned int json_quotes;

unsigned char JsonInterpret_Object(Json *pjson,Lexer_t *lexer,Json_Object *json_Object);
unsigned char JsonInterpret_Value(Json *pjson,Lexer_t *lexer,Json_Value *_value,unsigned char arrayElement);
void JsonFreeValue(Json *pjson,Json_Value *json_Value);

LEXER_LEXEME_TYPE JsonNextToken(Lexer_t *lexer)
{
	LEXER_LEXEME_TYPE type;
	while ((type= LexerGetNextLexeme(lexer))==LEXER_LEXEME_TYPE_SPACER||type==LEXER_LEXEME_TYPE_NEWLINE);

	return type;
}

Json_Value * JsonGetObjectValue(Json_Value *json_value,const char name[])
{
	int i;
	if (json_value->type!=JSON_VALUE_TYPE_OBJECT)
	{
		return NULL;
	}
	for (i=0;i<json_value->_object.values.size;i++)
	{
		Json_Value *pValue=LISTAT(Json_Value,&json_value->_object.values,i);
		if (strequ(name,pValue->name.buffer))
		{
			return pValue;
		}
	}
	return NULL;
}

Json_Value * JsonGetObjectValueByIndex(Json_Value *json_value,int i)
{
	if (i<0||i>=json_value->_object.values.size)
	{
		return NULL;
	}
	return LISTAT(Json_Value,&json_value->_object.values,i);
}

Json_Value* JsonValueGetValue(Json_Value* it, const char _payload[])
{
	int r_offset = 0;
	int s_offset = 0;
	char payload[256] = { 0 };
	char* lexeme = NULL;
	int i = 0, array = -1;

	if (in_strlen(_payload) >= sizeof(payload))
	{
		return NULL;
	}
	in_strset(payload, _payload);

	while (payload[r_offset] != 0)
	{

		while (TRUE)
		{
			if (payload[s_offset] == '.')
			{
				payload[s_offset] = '\0';
				s_offset++;
				break;
			}
			if (payload[s_offset] == '\0')
			{
				break;
			}
			s_offset++;
		}

		lexeme = payload + r_offset;
		i = in_strlen(lexeme);
		//array?
		if (lexeme[i - 1] == ']')
		{

			lexeme[i - 1] = '\0';
			i--;
			while (i > 0)
			{
				if (lexeme[i] == '[')
				{
					lexeme[i] = '\0';
					array = atoi(lexeme + i + 1);
					break;
				}
				i--;
			}
		}
		else
		{
			array = -1;
		}
		if (array != -1)
		{
			it = JsonGetObjectValue(it, lexeme);
			if (it && it->type == JSON_VALUE_TYPE_ARRAY)
			{
				it = JsonGetArrayValue(it, array);
			}
			else
			{
				return NULL;
			}

		}
		else
		{
			it = JsonGetObjectValue(it, lexeme);
		}

		r_offset = s_offset;
		if (!it)
		{
			break;
		}

	}
	return it;
}
Json_Value * JsonGetValue(Json *json,const char _payload[])
{
	return JsonValueGetValue(&json->rootValue, _payload);
}

Json_Value * JsonGetArrayValue(Json_Value *value,int i)
{
	if (value->type!=JSON_VALUE_TYPE_ARRAY)
	{
		return NULL;
	}
	if (i<value->_array.size)
	{
		return LISTAT(Json_Value,&value->_array,i);
	}
	return NULL;
}

unsigned char JsonInitialize(memorypool *mp,Json *pjson)
{
	in_memset(pjson,0,sizeof(Json));
	pjson->mp=mp;
	pjson->rootValue.type=JSON_VALUE_TYPE_OBJECT;
	StringInitialize(mp,&pjson->rootValue.name);
	ListInitialize(pjson->mp,&pjson->rootValue._object.values);
	return TRUE;	
}



static unsigned char JsonInterpret_Value_Array(Json *pjson,Lexer_t *lexer,Json_Value *_value)
{
	LEXER_LEXEME_TYPE type;
	Json_Value array_value;
	LEXER_STATE state;
	int i;
	type=JsonNextToken(lexer);

	if (type!=LEXER_LEXEME_TYPE_DELIMITER||lexer->Symbol!='[')
		goto _ERROR;

	while (TRUE)
	{
		state=LexerGetState(lexer);
		type=JsonNextToken(lexer);
		if (type==LEXER_LEXEME_TYPE_DELIMITER)
		{
			if(lexer->Symbol==']')
			{
				return TRUE;
			}

			if(lexer->Symbol!='{')
			{
				goto _ERROR;
			}	
		}
		
		LexerSetState(state);
		if (!JsonInterpret_Value(pjson,lexer,&array_value,TRUE))
		{
			goto _ERROR;
		}

		if(!ListPush(&_value->_array,&array_value,sizeof(array_value)))
			goto _ERROR;
			
		type=JsonNextToken(lexer);
		if (type==LEXER_LEXEME_TYPE_DELIMITER)
		{
			if (lexer->Symbol==',')
			{
				continue;
			}

			if (lexer->Symbol==']')
			{
				return TRUE;
			}
			goto _ERROR;
		}
		else
		{
			goto _ERROR;
		}
		
	}
_ERROR:
	for (i=0;i<_value->_array.size;i++)
	{
		JsonFreeValue(pjson,LISTAT(Json_Value,&_value->_array,i));
	}
	ListFree(&_value->_array);
	return FALSE;
}






unsigned char JsonInterpret_Value(Json *pjson,Lexer_t *lexer,Json_Value *_value,unsigned char arrayElement)
{
	LEXER_STATE state;
	LEXER_LEXEME_TYPE type;


	in_memset(_value,0,sizeof(Json_Value));
	StringInitialize(pjson->mp,&_value->name);
	if (!arrayElement)
	{
		type=JsonNextToken(lexer);
		if (type!=LEXER_LEXEME_TYPE_CONATINER)//{name
		{
			goto _ERROR;
		}
		LexerGetIncludedString(lexer,&lexer->CurLexeme);
		StringCopy(&_value->name,&lexer->CurLexeme);

		type=JsonNextToken(lexer);
		if (type!=LEXER_LEXEME_TYPE_DELIMITER||lexer->Symbol!=':')//{\spacer name :
		{
			goto _ERROR;
		}
	}

	state=LexerGetState(lexer);
	type=JsonNextToken(lexer);

	if (type==LEXER_LEXEME_TYPE_DELIMITER)
	{
		if(lexer->Symbol=='[')
		{
			LexerSetState(state);
			_value->type=JSON_VALUE_TYPE_ARRAY;
			ListInitialize(pjson->mp,&_value->_array);
			if(!JsonInterpret_Value_Array(pjson,lexer,_value))
			{
				
				goto _ERROR;
			}
			else
				return TRUE;
		}
		else
		if(lexer->Symbol=='{')
		{
			LexerSetState(state);
			_value->type=JSON_VALUE_TYPE_OBJECT;
			if(!JsonInterpret_Object(pjson,lexer,&_value->_object))
			{
				return FALSE;
			}
			return TRUE;

		}

		goto _ERROR;
		
	}
	else
	{
		if (type==LEXER_LEXEME_TYPE_TOKEN)
		{
			if(StringIsNumeric(&lexer->CurLexeme))
			{
				_value->type=JSON_VALUE_TYPE_NUMBER;
				_value->_number=atof(lexer->CurLexeme.buffer);
				return TRUE;
			}

			if(strequ(lexer->CurLexeme.buffer,"true"))
			{
				_value->type=JSON_VALUE_TYPE_BOOLEAN;
				_value->_boolean=TRUE;
				return TRUE;
			}

			if(strequ(lexer->CurLexeme.buffer,"false"))
			{
				_value->type=JSON_VALUE_TYPE_BOOLEAN;
				_value->_boolean=FALSE;
				return TRUE;
			}

			if(strequ(lexer->CurLexeme.buffer,"null"))
			{
				_value->type=JSON_VALUE_TYPE_NULL;
				return TRUE;
			}

			if (in_strlen(lexer->CurLexeme.buffer)>=3)
			{
				if (lexer->CurLexeme.buffer[0]=='0'&&(lexer->CurLexeme.buffer[1]=='x'||lexer->CurLexeme.buffer[1]=='X'))
				{
					_value->type=JSON_VALUE_TYPE_NUMBER;
					_value->_number=(unsigned char)htoi(lexer->CurLexeme.buffer+2);
					return TRUE;
				}
			}
		}
		else if(type==LEXER_LEXEME_TYPE_CONATINER&&lexer->CurrentContainerType==json_quotes)
		{
			int i;
			_value->type=JSON_VALUE_TYPE_STRING;
			if(!StringInitialize(pjson->mp,&_value->_string))goto _ERROR;;
			LexerGetIncludedString(lexer,&lexer->CurLexeme);
			
			if(!StringCopy(&_value->_string,&lexer->CurLexeme))
			{
				StringFree(&_value->_string);
				goto _ERROR;
			}
			
			for (i=0;_value->_string.buffer[i];i++)
			{
				if (_value->_string.buffer[i]=='\\')
				{
					if (_value->_string.buffer[i+1]=='\\')
					{
						StringRemoveChar(&_value->_string,i+1);
					}
					if (_value->_string.buffer[i+1]=='n')
					{
						_value->_string.buffer[i]='\n';
						StringRemoveChar(&_value->_string,i+1);
					}
					if (_value->_string.buffer[i+1]=='r')
					{
						_value->_string.buffer[i]='\r';
						StringRemoveChar(&_value->_string,i+1);
					}
					if (_value->_string.buffer[i+1]=='t')
					{
						_value->_string.buffer[i]='\t';
						StringRemoveChar(&_value->_string,i+1);
					}
				}
			}
			return TRUE;
		}
		
		goto _ERROR;

	}
_ERROR:
	StringFree(&_value->name);
	return FALSE;
}

unsigned char JsonInterpret_Object(Json *pjson,Lexer_t *lexer,Json_Object *json_Object)
{
	LEXER_LEXEME_TYPE type;
	Json_Value _value;
	LEXER_STATE state;
	int i;
	in_memset(json_Object,0,sizeof(Json_Object));
	
	if (!json_Object->values.mp)
	{
		ListInitialize(pjson->mp,&json_Object->values);
	}
	

	while (TRUE)
	{
		type=JsonNextToken(lexer);
		if (type==LEXER_LEXEME_TYPE_END)
		{
			goto _ERROR;
		}

		if (type==LEXER_LEXEME_TYPE_DELIMITER&&lexer->Symbol=='{')//{
		{
			state=LexerGetState(lexer);
			type=JsonNextToken(lexer);
			if (type==LEXER_LEXEME_TYPE_DELIMITER&&lexer->Symbol=='}')//{}
			{
				return TRUE;
			}
			else
			{
				LexerSetState(state);
				while (TRUE)
				{
					

					if (!JsonInterpret_Value(pjson,lexer,&_value,FALSE))
					{
						goto _ERROR;
					}

					if(!ListPush(&json_Object->values,&_value,sizeof(_value)))
						goto _ERROR;

					type=JsonNextToken(lexer);
					if (type!=LEXER_LEXEME_TYPE_DELIMITER)
					{
						goto _ERROR;
					}

					if (lexer->Symbol=='}')
					{
						return TRUE;
					}
					else if(lexer->Symbol==',')
					{
						continue;
					}
					else
					{
						goto _ERROR;
					}
				}
			}
		}
	}
_ERROR:
	//////////////////////////////////////////////////////////////////////////
	//remove object
	
	for (i=0;i<json_Object->values.size;i++)
	{
		JsonFreeValue(pjson,LISTAT(Json_Value,&json_Object->values,i));
	}
	ListFree(&json_Object->values);

	return FALSE;
}

unsigned char JsonParse(Json *pjson,const char *json_content)
{
	Lexer_t lexer;
	
	LexerInitialize(&lexer,pjson->mp);
	LexerRegisterDelimiter(&lexer,',');
	LexerRegisterDelimiter(&lexer,':');
	LexerRegisterDelimiter(&lexer,'{');
	LexerRegisterDelimiter(&lexer,'}');
	LexerRegisterDelimiter(&lexer,'[');
	LexerRegisterDelimiter(&lexer,']');
	LexerRegisterSpacer(&lexer,' ');
	LexerRegisterSpacer(&lexer,'\t');
	LexerRegisterComment(&lexer,"//","\n");
	json_quotes=LexerRegisterContainer(&lexer,"\"","\"");
	if(!LexerLoadSourceFromMemory(&lexer,json_content)) goto _ERROR;

	if(!JsonInterpret_Object(pjson,&lexer,&pjson->rootValue._object))
		goto _ERROR;
	LexerFree(&lexer);
	return TRUE;
_ERROR:
	LexerFree(&lexer);
	return FALSE;
}

unsigned char JsonBuild_Value(Json_Value *pValue,String_t *_out,unsigned char bArrayValue)
{
	if (!bArrayValue)
	{
		//name
		if(!StringCatCharEx(_out,'"'))return FALSE;
		if(!StringCatEx(_out,pValue->name.buffer)) return FALSE;
		if(!StringCatCharEx(_out,'"'))return FALSE;
		//:
		if(!StringCatCharEx(_out,':')) return FALSE;
	}

	switch(pValue->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{
			int i;
			if(!StringCatCharEx(_out,'['))return FALSE;
			for (i=0;i<pValue->_array.size;i++)
			{
				Json_Value *pv=LISTAT(Json_Value,&pValue->_array,i);
				if(!JsonBuild_Value(pv,_out,TRUE))return FALSE;
				if(i!=pValue->_array.size-1)if(!StringCatCharEx(_out,','))return FALSE;
			}
			if(!StringCatCharEx(_out,']'))return FALSE;
		}
		break;
	case JSON_VALUE_TYPE_BOOLEAN:
		{
			if (pValue->_boolean)
			{
				if(!StringCatEx(_out,"true"))return FALSE;
			}
			else
			{
				if(!StringCatEx(_out,"false"))return FALSE;
			}
		}
		break;
	case JSON_VALUE_TYPE_NULL:
		{
			if(!StringCatEx(_out,"null"))return FALSE;
		}
		break;
	case JSON_VALUE_TYPE_NUMBER:
		{
		return_string ret = ftos((float)pValue->_number, 6);
		if(!StringCatEx(_out, ret.data))return FALSE;
		}
		break;
	case JSON_VALUE_TYPE_STRING:
		{
			if(!StringCatEx(_out,"\""))return FALSE;
			if(!StringCatEx(_out,pValue->_string.buffer))return FALSE;
			if(!StringCatEx(_out,"\""))return FALSE;
		}
		break;
	case JSON_VALUE_TYPE_OBJECT:
		{
			int i;
			if(!StringCatEx(_out,"{\n")) return FALSE;
			for (i=0;i<pValue->_object.values.size;i++)
			{
				Json_Value *ptmpValue=LISTAT(Json_Value,&pValue->_object.values,i);
				if(!JsonBuild_Value(ptmpValue,_out,FALSE))return FALSE;
				if(i!=pValue->_object.values.size-1)if(!StringCatEx(_out,",")) return FALSE;
				if(!StringCatEx(_out,"\n")) return FALSE;
			}
			if(!StringCatEx(_out,"}")) return FALSE;
		}
		break;
	}
	return TRUE;
}


unsigned char JsonBuild(Json *pjson,String_t *_out)
{
	StringUpdateExReg(_out);
	return JsonBuild_Value(&pjson->rootValue,_out,TRUE);
}

static void JsonDeleteValue(Json *pjson,Json_Value *pValue)
{
	switch (pValue->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{
			int i;
			for (i=0;i<pValue->_array.size;i++)
			{
				Json_Value *pSubValue=LISTAT(Json_Value,&pValue->_array,i);
				JsonDeleteValue(pjson,pSubValue);
			}
			ListFree(&pValue->_array);
		}
		break;
	case JSON_VALUE_TYPE_OBJECT:
		{
			int i;
			for (i=0;i<pValue->_object.values.size;i++)
			{
				Json_Value *pSubValue=LISTAT(Json_Value,&pValue->_object.values,i);
				JsonDeleteValue(pjson,pSubValue);
			}
			ListFree(&pValue->_object.values);
		}
		break;
	case JSON_VALUE_TYPE_STRING:
		{
			StringFree(&pValue->_string);
		}
		break;
	default:
		break;
	}
}


void JsonDelete(Json *pjson,const char _payload[])
{
	int i;
	Json_Value *pParentValue,*pValue;
	char payload[256]={0};


	if (in_strlen(_payload)>=sizeof(payload))
	{
		return;
	}

	pValue=JsonGetValue(pjson,_payload);
	if (!pValue)
	{
		return;
	}

	in_strset(payload,_payload);

	if (payload[in_strlen(payload)-1]==']')
	{
		//array
		for (i=in_strlen(payload);i>0;i--)
		{
			if (payload[i]=='[')
			{
				break;
			}
		}
	}
	else
	{
		for (i=in_strlen(payload);i>0;i--)
		{
			if (payload[i]=='.')
			{
				break;
			}
		}
	}
	payload[i]='\0';
	pParentValue=JsonGetValue(pjson,payload);

	if (!pParentValue)
	{
		return;
	}
	switch(pParentValue->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{
			int j;
			for (j=0;j<pParentValue->_array.size;j++)
			{
				Json_Value *pTarget;
				pTarget=LISTAT(Json_Value,&pParentValue->_array,j);
				if (pTarget==pValue)
				{
					JsonDeleteValue(pjson,pTarget);
					ListErase(&pParentValue->_array,j);
					return;
				}
			}
		}
		break;
	case JSON_VALUE_TYPE_OBJECT:
		{
			int j;
			for (j=0;j<pParentValue->_object.values.size;j++)
			{
				Json_Value *pTarget;
				pTarget=LISTAT(Json_Value,&pParentValue->_object.values,j);
				if (pTarget==pValue)
				{
					JsonDeleteValue(pjson,pTarget);
					ListErase(&pParentValue->_object.values,j);
					return;
				}
			}
		}
		break;
	default:
		break;
	}


}

void JsonFreeValue(Json *pjson,Json_Value *json_Value)
{
	StringFree(&json_Value->name);
	switch (json_Value->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{
			int i;
			for (i=0;i<json_Value->_array.size;i++)
			{
				JsonFreeValue(pjson,LISTAT(Json_Value,&json_Value->_array,i));
			}
			ListFree(&json_Value->_array);
		}
		break;
	case JSON_VALUE_TYPE_STRING:
		StringFree(&json_Value->_string);
		break;
	case JSON_VALUE_TYPE_OBJECT:
		{
			int i;
			for (i=0;i<json_Value->_object.values.size;i++)
			{
				JsonFreeValue(pjson,LISTAT(Json_Value,&json_Value->_object.values,i));
			}
			ListFree(&json_Value->_object.values);
		}
		break;
	case JSON_VALUE_TYPE_BOOLEAN:
	case JSON_VALUE_TYPE_NULL:
	case JSON_VALUE_TYPE_NUMBER:
	default:
		break;
	}
}

void JsonFree(Json *pjson)
{
	JsonFreeValue(pjson,&pjson->rootValue);
}

void JsonClear(Json* pjson)
{
	JsonFreeValue(pjson, &pjson->rootValue);
}

unsigned char JsonCreateObjectValue(memorypool *mp,Json_Value *pValue,const char name[])
{
	in_memset(pValue,0,sizeof(Json_Value));
	pValue->type=JSON_VALUE_TYPE_OBJECT;

	if (!StringInitialize(mp,&pValue->name))
	{
		return FALSE;
	}
	if(!StringSet(&pValue->name,name)) return FALSE;
	ListInitialize(mp,&pValue->_object.values);
	return TRUE;
}

unsigned char JsonCreateStringValue(memorypool *mp,Json_Value *pValue,const char name[],const char text[])
{
	in_memset(pValue,0,sizeof(Json_Value));
	pValue->type=JSON_VALUE_TYPE_STRING;

	if (!StringInitialize(mp,&pValue->name))
	{
		return FALSE;
	}
	StringSet(&pValue->name,name);

	if (!StringInitialize(mp,&pValue->_string))
	{
		return FALSE;
	}
	if(!StringSet(&pValue->_string,text)) return FALSE;
	return TRUE;
}

unsigned char JsonCreateNumberValue(memorypool *mp,Json_Value *pValue,const char name[],double value)
{
	in_memset(pValue,0,sizeof(Json_Value));
	pValue->type=JSON_VALUE_TYPE_NUMBER;

	if (!StringInitialize(mp,&pValue->name))
	{
		return FALSE;
	}
	if(!StringSet(&pValue->name,name)) return FALSE;

	pValue->_number=value;
	return TRUE;
}

unsigned char JsonCreateBooleanValue(memorypool *mp,Json_Value *pValue,const char name[],unsigned char b)
{
	in_memset(pValue,0,sizeof(Json_Value));
	pValue->type=JSON_VALUE_TYPE_BOOLEAN;

	if (!StringInitialize(mp,&pValue->name))
	{
		return FALSE;
	}
	if(!StringSet(&pValue->name,name)) return FALSE;

	pValue->_boolean=b;
	return TRUE;
}

unsigned char JsonCreateArrayValue(memorypool *mp,Json_Value *pValue,const char name[])
{
	in_memset(pValue,0,sizeof(Json_Value));
	pValue->type=JSON_VALUE_TYPE_ARRAY;

	if (!StringInitialize(mp,&pValue->name))
	{
		return FALSE;
	}
	if(!StringSet(&pValue->name,name)) return FALSE;
	ListInitialize(mp,&pValue->_array);
	return TRUE;
}

unsigned char JsonAddString(Json *pjson,const char parent_payload[],const char name[],const char text[])
{
	Json_Value *pValue=JsonGetValue(pjson,parent_payload);
	
	Json_Value newValue;
	if (!pValue)
	{
		return FALSE;
	}
	switch (pValue->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{
			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateStringValue(pjson->mp,&newValue,name,text);
				ListPush(&pValue->_array,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_STRING)
				{
					return FALSE;
				}
				StringSet(&pExistValue->_string,text);
			}
			
			
			return TRUE;
		}
		//break;
	case JSON_VALUE_TYPE_OBJECT:
		{
			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateStringValue(pjson->mp,&newValue,name,text);
				ListPush(&pValue->_object.values,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_STRING)
				{
					return FALSE;
				}
				StringSet(&pExistValue->_string,text);
			}
			return TRUE;
		}
		//break;
	default:
		return FALSE;
	}

	return FALSE;
}

unsigned char JsonAddNumber(Json *pjson,const char parent_payload[],const char name[],const double number)
{
	Json_Value *pValue=JsonGetValue(pjson,parent_payload);
	Json_Value newValue;
	if (!pValue)
	{
		return FALSE;
	}
	switch (pValue->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{

			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateNumberValue(pjson->mp,&newValue,name,number);
				ListPush(&pValue->_array,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_NUMBER)
				{
					return FALSE;
				}
				pExistValue->_number=number;
			}

			
			return TRUE;
		}
		//break;
	case JSON_VALUE_TYPE_OBJECT:
		{
			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateNumberValue(pjson->mp,&newValue,name,number);
				ListPush(&pValue->_object.values,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_NUMBER)
				{
					return FALSE;
				}
				pExistValue->_number=number;
			}
			return TRUE;
		}
		//break;
	default:
		return FALSE;
	}

	return FALSE;


}

unsigned char JsonAddBoolean(Json *pjson,const char parent_payload[],const char name[],const unsigned char b)
{
	Json_Value *pValue=JsonGetValue(pjson,parent_payload);
	Json_Value newValue;
	if (!pValue)
	{
		return FALSE;
	}
	switch (pValue->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{
			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateBooleanValue(pjson->mp,&newValue,name,b);
				ListPush(&pValue->_array,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_BOOLEAN)
				{
					return FALSE;
				}
				pExistValue->_boolean=b;
			}

			return TRUE;
		}
		//break;
	case JSON_VALUE_TYPE_OBJECT:
		{
			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateBooleanValue(pjson->mp,&newValue,name,b);
				ListPush(&pValue->_object.values,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_BOOLEAN)
				{
					return FALSE;
				}
				pExistValue->_boolean=b;
			}

			return TRUE;
		}
		//break;
	default:
		return FALSE;
	}

	return FALSE;
}

unsigned char JsonAddArray(Json *pjson,const char parent_payload[],const char name[])
{
	Json_Value *pValue=JsonGetValue(pjson,parent_payload);
	Json_Value newValue;
	if (!pValue)
	{
		return FALSE;
	}
	switch (pValue->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{
			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateArrayValue(pjson->mp,&newValue,name);
				ListPush(&pValue->_array,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_ARRAY)
				{
					return FALSE;
				}
			}

			return TRUE;
		}
		//break;
	case JSON_VALUE_TYPE_OBJECT:
		{
			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateArrayValue(pjson->mp,&newValue,name);
				ListPush(&pValue->_object.values,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_ARRAY)
				{
					return FALSE;
				}
			}
			
			return TRUE;
		}
		//break;
	default:
		return FALSE;
	}

	return FALSE;
}

unsigned char JsonAddObject(Json *pjson,const char parent_payload[],const char name[])
{
	Json_Value *pValue=JsonGetValue(pjson,parent_payload);
	Json_Value newValue;
	if (!pValue)
	{
		return FALSE;
	}
	switch (pValue->type)
	{
	case JSON_VALUE_TYPE_ARRAY:
		{

			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateObjectValue(pjson->mp,&newValue,name);
				ListPush(&pValue->_array,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_OBJECT)
				{
					return FALSE;
				}
			}

			
			return TRUE;
		}
		//break;
	case JSON_VALUE_TYPE_OBJECT:
		{

			Json_Value *pExistValue=JsonGetObjectValue(pValue,name);
			if (!pExistValue)
			{
				JsonCreateObjectValue(pjson->mp,&newValue,name);
				ListPush(&pValue->_object.values,&newValue,sizeof(newValue));
			}
			else
			{
				if (pExistValue->type!=JSON_VALUE_TYPE_OBJECT)
				{
					return FALSE;
				}
			}
			return TRUE;
		}
		//break;
	default:
		return FALSE;
	}

	return FALSE;
}

const char * JsonGetString(Json *pjson,const char payload[])
{
	Json_Value *pValue=JsonGetValue(pjson,payload);
	if (pValue&&pValue->type==JSON_VALUE_TYPE_STRING)
	{
		return pValue->_string.buffer;
	}
	return "";
}

double JsonGetNumber(Json *pjson,const char payload[])
{
	Json_Value *pValue=JsonGetValue(pjson,payload);
	if (pValue&&pValue->type==JSON_VALUE_TYPE_NUMBER)
	{
		return pValue->_number;
	}
	return 0;
}

// px_color JsonGetColor(Json* pjson, const char payload[])
// {
// 	Json_Value* pValue = JsonGetValue(pjson, payload);
// 	if (pValue && pValue->type == JSON_VALUE_TYPE_ARRAY)
// 	{
// 		if (pValue->_array.size==4)
// 		{
// 			px_byte a,r, g, b;
// 			Json_Value* pArrayValue;
// 			pArrayValue =LISTAT(Json_Value,&pValue->_array,0);
// 			if (pArrayValue->type!=JSON_VALUE_TYPE_NUMBER)
// 			{
// 				goto _ERROR;
// 			}
// 			a = (px_byte)pArrayValue->_number;
// 			//r
// 			pArrayValue =LISTAT(Json_Value,&pValue->_array,1);
// 			if (pArrayValue->type!=JSON_VALUE_TYPE_NUMBER)
// 			{
// 				goto _ERROR;
// 			}
// 			r = (px_byte)pArrayValue->_number;
// 			//g
// 			pArrayValue =LISTAT(Json_Value,&pValue->_array,2);
// 			if (pArrayValue->type!=JSON_VALUE_TYPE_NUMBER)
// 			{
// 				goto _ERROR;
// 			}
// 			g = (px_byte)pArrayValue->_number;
// 			//b
// 			pArrayValue =LISTAT(Json_Value,&pValue->_array,3);
// 			if (pArrayValue->type!=JSON_VALUE_TYPE_NUMBER)
// 			{
// 				goto _ERROR;
// 			}
// 			b = (px_byte)pArrayValue->_number;
// 			return COLOR(a,r,g,b);

// 		}
		
// 	}
// 	_ERROR:
// 	return COLOR_WHITE;
// }


unsigned char JsonGetBoolean(Json *pjson,const char payload[])
{
	Json_Value *pValue=JsonGetValue(pjson,payload);
	if (pValue&&pValue->type==JSON_VALUE_TYPE_BOOLEAN)
	{
		return pValue->_boolean;
	}
	return 0;
}

const char* JsonValueGetString(Json_Value* _pValue, const char payload[])
{
	Json_Value* pValue = JsonValueGetValue(_pValue, payload);
	if (pValue && pValue->type == JSON_VALUE_TYPE_STRING)
	{
		return pValue->_string.buffer;
	}
	return "";
}

double JsonValueGetNumber(Json_Value* _pValue, const char payload[])
{
	Json_Value* pValue = JsonValueGetValue(_pValue, payload);
	if (pValue && pValue->type == JSON_VALUE_TYPE_NUMBER)
	{
		return pValue->_number;
	}
	return 0;
}

unsigned char JsonValueGetBoolean(Json_Value* _pValue, const char payload[])
{
	Json_Value* pValue = JsonValueGetValue(_pValue, payload);
	if (pValue && pValue->type == JSON_VALUE_TYPE_BOOLEAN)
	{
		return pValue->_boolean;
	}
	return 0;
}

unsigned char JsonSetString(Json *pjson,const char payload[],const char text[])
{
	Json_Value *pValue=JsonGetValue(pjson,payload);
	if (pValue&&pValue->type==JSON_VALUE_TYPE_STRING)
	{
		return StringSet(&pValue->_string,text);
	}
	return FALSE;
}

unsigned char JsonSetNumber(Json *pjson,const char payload[],const double number)
{
	Json_Value *pValue=JsonGetValue(pjson,payload);
	if (pValue&&pValue->type==JSON_VALUE_TYPE_NUMBER)
	{
		pValue->_number=number;
		return TRUE;
	}
	return FALSE;
}

unsigned char JsonSetBoolean(Json *pjson,const char payload[],const unsigned char b)
{
	Json_Value *pValue=JsonGetValue(pjson,payload);
	if (pValue&&pValue->type==JSON_VALUE_TYPE_BOOLEAN)
	{
		pValue->_boolean=b;
		return TRUE;
	}
	return FALSE;
}

unsigned char JsonObjectAddValue(Json_Value *pObject,Json_Value *value)
{
	if (pObject->type==JSON_VALUE_TYPE_OBJECT)
	{
		return ListPush(&pObject->_object.values,value,sizeof(Json_Value))!=NULL;
	}
	return FALSE;
}

unsigned char JsonArrayAddValue(Json_Value *pArray,Json_Value *value)
{
	if (pArray->type==JSON_VALUE_TYPE_ARRAY)
	{
		return ListPush(&pArray->_array,value,sizeof(Json_Value))!=NULL;
	}
	return FALSE;
}

